package com.cpit.qualitycontrol.service.impl;

import com.cpit.platform.common.constant.SystemConstant;
import com.cpit.platform.common.entity.TableDataQueryCondition;
import com.cpit.platform.common.entity.TableJsonData;
import com.cpit.platform.dao.OrganizationRepository;
import com.cpit.platform.dto.Organization;
import com.cpit.platform.dto.User;
import com.cpit.platform.log.LogOperator;
import com.cpit.platform.security.service.UserInfo;
import com.cpit.qualitycontrol.dao.DeviceRepository;
import com.cpit.qualitycontrol.dao.ProcessRuleRepository;
import com.cpit.qualitycontrol.dao.ProjectOrganizationRepository;
import com.cpit.qualitycontrol.dao.ProjectRepository;
import com.cpit.qualitycontrol.dao.jpqlquery.ProjectQueryRepository;
import com.cpit.qualitycontrol.entity.*;
import com.cpit.qualitycontrol.service.ProjectService;
import com.cpit.qualitycontrol.service.UserToProductLineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional(rollbackFor = Exception.class)
public class ProjectServiceImpl implements ProjectService {


    private final String loggerName = this.getClass().getName();

    @Autowired
    private ProjectRepository rep = null;
    @Autowired
    private ProjectQueryRepository queryRepository = null;
    @Autowired
    private ProjectOrganizationRepository porep = null;
    @Autowired
    private OrganizationRepository organizationRepository;
    @Autowired
    private DeviceRepository deviceRepository;
    @Autowired
    private ProcessRuleRepository processRuleRepository;

    @Autowired
    private UserToProductLineService userToProductLineService;

    @Override
    public List<Project> findAll() {
        Long productLineId = null;

        List<UserToProductLine> list = userToProductLineService.findByUserId(getLoginUser().getId());
        if (list != null && list.size() > 0) {//产品线角色
            productLineId = new Long((long) list.get(0).getProductLineId());
        }

        return this.queryRepository.findByCondition(productLineId, null);
    }

    @Override
    public List<Project> findByCondition(int page, int size, String order, String orderBy, String pattern) {
        if (orderBy == null || orderBy.length() == 0) {
            orderBy = "id";
        }
        Sort.Direction der = order.equals(SystemConstant.DIRECTION_ASC) ? Sort.Direction.ASC : Sort.Direction.DESC;
        PageRequest request = new PageRequest(page - 1, size, new Sort(der, orderBy));
        Page<Project> pg = null;
        if (pattern == null || pattern.equals(""))
            pg = this.rep.findAll(request);
        else
            pg = this.rep.findByNameContaining(pattern, request);
        return pg.getContent();
    }

    @Override
    public List<Project> findByCondition(int page,
                                         int size,
                                         String order,
                                         String orderBy,
                                         Long productLineId, String projectName) {
        if (orderBy == null || orderBy.length() == 0) {
            orderBy = "id";
        }
        Sort.Direction der = order.equals(SystemConstant.DIRECTION_ASC) ? Sort.Direction.ASC : Sort.Direction.DESC;
        PageRequest request = new PageRequest(page - 1, size, new Sort(der, orderBy));
        List<UserToProductLine> list = userToProductLineService.findByUserId(getLoginUser().getId());
        if (list != null && list.size() > 0) {//产品线角色
            productLineId = new Long((long) list.get(0).getProductLineId());
        }
        return queryRepository.findByCondition(productLineId, projectName, request).getContent();

    }

    @Override
    public Project create(Project project) throws Exception {
        if (project == null)
            throw new Exception("参数为空");
        if (project.getId() != null && project.getId() > 0)
            LogOperator.info(loggerName, "ProjectID已赋值");
        Project dt = rep.findByName(project.getName());
        if (dt != null)
            throw new Exception("同名项目已存在:" + project.getName());

        //创建Project之后才有project id
        Project saved = this.rep.save(project);
//        saved.setConstructionOrganization(project.getConstructionOrganization());
//          /*创建关联的组织结构关系*/
//        createProjectOrganization(saved);
        return saved;
    }

    @Override
    public Project modify(Project project) throws Exception {
        if (project == null)
            throw new Exception("参数为空");
        Project dt = rep.findById(project.getId());
        if (dt == null)
            throw new Exception("修改的项目不存在:" + project);
        dt = rep.findByName(project.getName());
        if (dt != null && !dt.getId().equals(project.getId()))
            throw new Exception("同名项目已存在:" + project.getName());

//        /*先删除关联的组织结构再创建新的组织结构关系*/
//        List<ProjectOrganization> list = porep.findByProjectId(project.getId());

      /* porep.deleteInBatch(list);
        for ( ProjectOrganization po:
                list ) {
            LogOperator.info(loggerName, "删除的组织结构：" + po.toString()+"\n");
        }*/
//        porep.deleteByProjectId(project.getId());
//        createProjectOrganization(project);
        return this.rep.save(project);
    }

    /**
     * 创建关联的组织结构关系
     *
     * @param project
     */
    private void createProjectOrganization(Project project) {
        for (Organization org : project.getConstructionOrganization()) {
//            LogOperator.info(loggerName, "传下来的组织结构：" + org.toString() + "\n");
            ProjectOrganization projectOrganization = new ProjectOrganization();
            projectOrganization.setOrganizationId(org.getId());
            projectOrganization.setProjectId(project.getId());
            projectOrganization.setOrganizationName(org.getName());
            porep.save(projectOrganization);
//            LogOperator.info(loggerName, "保存的组织结构：" + projectOrganization.toString() + "\n");
        }
    }

    @Override
    public void delete(Project project) throws Exception {
        if (project == null)
            throw new Exception("参数为空");

        Project dt = rep.findById(project.getId());
        if (dt == null)
            throw new Exception("删除的项目不存在:" + project);
         /*检查是否存在关联的子对象 device processrule*/
        List<Device> devices = deviceRepository.findByProjectId(project.getId());
        if (devices != null && devices.size() > 0) {
            throw new Exception("删除的项目还存在子对象Device，不能删除:" + project);
        }
        List<ProcessRule> processRules = processRuleRepository.findByProjectId(project.getId());
        if (processRules != null && processRules.size() > 0) {
            throw new Exception("删除的项目还存在子对象ProcessRule，不能删除:" + project);
        }
//        /*删除关联的组织机构关系*/
//        //传下来的project中不含有组织的信息
//        porep.deleteByProjectId(project.getId());
        rep.delete(project);

    }

    public Project findById(Long id) {
        Project project = rep.findById(id);
        setOrganization(project);
        return project;
    }

    @Override
    public List<ProjectOrganization> findByOrganizationId(Integer organizationId) {
        return porep.findByOrganizationId(organizationId);
    }

    @Override
    public TableJsonData findByConditionJqg(TableDataQueryCondition cond) {

        PageRequest request = ServiceUtils.getPageRequestByTableDataQueryCondition(cond);

        Map queryCondMap = cond.getQueryCond();
        String projectName = (String) queryCondMap.get("name");
        Long productLineId = null;
        String strPLid = (String) queryCondMap.get("productLineId");
        if (strPLid != null && (!strPLid.equals(""))) {
            productLineId = Long.valueOf(strPLid);
        }

        List<UserToProductLine> list = userToProductLineService.findByUserId(getLoginUser().getId());
        if (list != null && list.size() > 0) {//产品线角色
            productLineId = new Long((long) list.get(0).getProductLineId());
        }

        Page<Project> ret = this.queryRepository.findByCondition(productLineId, projectName, request);

        return new TableJsonData(cond, ret.getTotalElements(), ret.getContent());
    }

    /**
     * 获取登录用户信息
     *
     * @return
     */
    private User getLoginUser() {
        return ((UserInfo) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal()).getUser();
    }

    /**
     * 将关联的组织赋值
     *
     * @param project
     */
    private void setOrganization(Project project) {
        List<Organization> organizations = organizationRepository.findAll();
        Map<Integer, Organization> organizationMap = new HashMap<Integer, Organization>();
        for (Organization org : organizations) {
            organizationMap.put(org.getId(), org);
        }
        List<ProjectOrganization> polist = porep.findByProjectId(project.getId());
        for (ProjectOrganization po : polist) {
            project.addOrganization(organizationMap.get(po.getOrganizationId()));
        }


    }

}
